Make the gif loader handle oom when loading animations. (#168857, Tommi
authorMatthias Clasen <mclasen@redhat.com>
Thu, 3 Mar 2005 13:29:01 +0000 (13:29 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Thu, 3 Mar 2005 13:29:01 +0000 (13:29 +0000)
2005-03-03  Matthias Clasen  <mclasen@redhat.com>

Make the gif loader handle oom when loading
animations.  (#168857, Tommi Komulainen)

* io-gif-animation.c (gdk_pixbuf_gif_anim_frame_composite):
Handle oom by returning NULL.

* io-gif.c (gif_get_lzw): Return an error if composite
returns NULL.

gdk-pixbuf/ChangeLog
gdk-pixbuf/io-gif-animation.c
gdk-pixbuf/io-gif.c

index b12f76a831b32df7c298b922265f7b5035ee3838..b03ae2395801b6ab36fa16593bb0272e15700aef 100644 (file)
@@ -1,3 +1,14 @@
+2005-03-03  Matthias Clasen  <mclasen@redhat.com>
+
+       Make the gif loader handle oom when loading 
+       animations.  (#168857, Tommi Komulainen)
+       
+       * io-gif-animation.c (gdk_pixbuf_gif_anim_frame_composite): 
+       Handle oom by returning NULL.
+
+       * io-gif.c (gif_get_lzw): Return an error if composite 
+       returns NULL.
+
 2005-02-28  Matthias Clasen  <mclasen@redhat.com>
 
        * pixops/*.S: Add .note.GNU-stack sections to Mark these as not 
index 96c0139e5ea5618164a44e544a958a6dbf5fe712..fe40df834a144016a513d186dd42836f3b7450ac 100644 (file)
@@ -391,6 +391,10 @@ gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
                 
                 while (tmp != NULL) {
                         GdkPixbufFrame *f = tmp->data;
+
+                        if (f->pixbuf == NULL)
+                                return;
+
                         gint clipped_width = MIN (gif_anim->width - f->x_offset, gdk_pixbuf_get_width (f->pixbuf));
                         gint clipped_height = MIN (gif_anim->height - f->y_offset, gdk_pixbuf_get_height (f->pixbuf));
   
@@ -414,6 +418,9 @@ gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
                                                                 TRUE,
                                                                 8, gif_anim->width, gif_anim->height);
 
+                                if (f->composited == NULL)
+                                        return;
+
                                 /* alpha gets dumped if f->composited has no alpha */
                                 
                                 gdk_pixbuf_fill (f->composited,
@@ -453,9 +460,16 @@ gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
                                 
                                 if (prev_frame->action == GDK_PIXBUF_FRAME_RETAIN) {
                                         f->composited = gdk_pixbuf_copy (prev_frame->composited);
+
+                                        if (f->composited == NULL)
+                                                return;
                                         
                                 } else if (prev_frame->action == GDK_PIXBUF_FRAME_DISPOSE) {
                                         f->composited = gdk_pixbuf_copy (prev_frame->composited);
+
+                                        if (f->composited == NULL)
+                                                return;
+
                                         if (prev_clipped_width > 0 && prev_clipped_height > 0) {
                                                 /* Clear area of previous frame to background */
                                                 GdkPixbuf *area;
@@ -465,6 +479,9 @@ gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
                                                                                  prev_frame->y_offset,
                                                                                  prev_clipped_width,
                                                                                  prev_clipped_height);
+
+                                                if (area == NULL)
+                                                        return;
                                                 
                                                 gdk_pixbuf_fill (area,
                                                                  (gif_anim->bg_red << 24) |
@@ -475,7 +492,12 @@ gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
                                         }                                        
                                 } else if (prev_frame->action == GDK_PIXBUF_FRAME_REVERT) {
                                         f->composited = gdk_pixbuf_copy (prev_frame->composited);
-                                        if (prev_clipped_width > 0 && prev_clipped_height > 0) {
+
+                                        if (f->composited == NULL)
+                                                return;
+
+                                        if (prev_frame->revert != NULL &&
+                                            prev_clipped_width > 0 && prev_clipped_height > 0) {
                                                 /* Copy in the revert frame */
                                                 gdk_pixbuf_copy_area (prev_frame->revert,
                                                                       0, 0,
@@ -500,14 +522,21 @@ gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
                                                                                  f->y_offset,
                                                                                  clipped_width,
                                                                                  clipped_height);
+                                            
+                                                if (area == NULL)
+                                                        return;
                                                 
                                                 f->revert = gdk_pixbuf_copy (area);
-                                                
+
                                                 g_object_unref (area);
+
+                                                if (f->revert == NULL)
+                                                        return;
                                         }
                                 }
 
-                                if (clipped_width > 0 && clipped_height > 0) {
+                                if (clipped_width > 0 && clipped_height > 0 &&
+                                    f->pixbuf != NULL && f->composited != NULL) {
                                         /* Put current frame onto f->composited */
                                         gdk_pixbuf_composite (f->pixbuf,
                                                               f->composited,
@@ -531,10 +560,6 @@ gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
                         tmp = tmp->next;
                 }
         }
-
-        g_assert (frame->composited != NULL);
-        g_assert (gdk_pixbuf_get_width (frame->composited) == gif_anim->width);
-        g_assert (gdk_pixbuf_get_height (frame->composited) == gif_anim->height);
 }
 
 GdkPixbuf*
index fd78e586aa70169ef64fbdd9e49d6c632f5f5890..4aa099a82d9f84c73e1c095503bc19dd01de30a3 100644 (file)
@@ -920,6 +920,34 @@ gif_get_lzw (GifContext *context)
 
                         gdk_pixbuf_gif_anim_frame_composite (context->animation, prev_frame);
 
+                        /* Composite failed */
+                        if (prev_frame->composited == NULL) {
+                                GdkPixbufFrame *frame = NULL;
+                                link = g_list_first (context->animation->frames);
+                                while (link != NULL) {
+                                        frame = (GdkPixbufFrame *)link->data;
+                                        if (frame != NULL) {
+                                                if (frame->pixbuf != NULL)
+                                                        g_object_unref (frame->pixbuf);
+                                                if (frame->composited != NULL)
+                                                        g_object_unref (frame->composited);
+                                                if (frame->revert != NULL)
+                                                        g_object_unref (frame->revert);
+                                                g_free (frame);
+                                        }
+                                        link = link->next;
+                                }
+                                
+                                g_list_free (context->animation->frames);
+                                context->animation->frames = NULL;
+                                
+                                g_set_error (context->error,
+                                             GDK_PIXBUF_ERROR,
+                                             GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+                                             _("Not enough memory to composite a frame in GIF file"));
+                                return -2;
+                        }
+                    
                         x = context->frame->x_offset;
                         y = context->frame->y_offset;
                         w = gdk_pixbuf_get_width (context->frame->pixbuf);